//
//  FBtSession.m
//  JwPack
//
//  Created by 陈警卫 on 2025/7/25.
//

#import "FBtSession.h"
#import "JwPack-Swift.h"

#import "FBtCorer.h"
#import "FBtSession+Model.h"

@interface FBtSession ()

@property (nonatomic, strong) NSMutableData *receiveCacheData;

/// 数据写入间隔(默认0.1s)
@property (nonatomic, assign) CGFloat writeInterval;

@property (nonatomic, strong) dispatch_source_t writeTimer;
/// 心跳长连接
@property (nonatomic, strong) dispatch_source_t heartTimer;

@property (nonatomic, strong) NSMutableArray<FBtMessageModel *> *sendMessageModels;
/// 已发送等待接收字典 key: messageModel.key
@property (nonatomic, strong) NSMutableDictionary *sendReceiveParams;


@end

@implementation FBtSession

- (instancetype)init {
    self = [super init];
    if (self) {
        self.receiveCacheData = [NSMutableData data];
        
        self.writeInterval = 0.1;
        self.sendMessageModels = [NSMutableArray array];
        
        self.sendReceiveParams = [NSMutableDictionary dictionary];
    }
    return self;
}

/// 接受数据
- (void)receiveData:(NSData *)data periModel:(FBtPeriModel *)periModel {
    if ([self isCompledData:data]) {
        // 正确数据解析数据
        [self handleCompledData:data periModel:periModel];
    } else {
        // 错误数据处理分包
        kFBtLog(@"接收错误数据--%@", data);
        [self.receiveCacheData appendData:data];
        if (self.receiveCacheData.length >= 13) {
            [self handleSubcontractPeriModel:periModel];
        }
    }
}

/// 验证数据
- (BOOL)isCompledData:(NSData *)data {
    BOOL isCompled = NO;
    if (data.length >= 13) {
        NSData *preData = [data subdataWithRange:(NSMakeRange(0, 2))];
        NSData *sufData = [data subdataWithRange:(NSMakeRange(data.length - 2, 2))];
        
        Byte perByte[2] = {0x7F, 0x7F};
        Byte sufByte[2] = {0xF7, 0xF7};
        Byte perByte_b[2] = {0x7E, 0x7E};
        Byte sufByte_b[2] = {0xE7, 0xE7};
        
        if ([preData isEqualToData:[NSData dataWithBytes:perByte length:sizeof(perByte)]] ||
            [sufData isEqualToData:[NSData dataWithBytes:sufByte length:sizeof(sufByte)]] ||
            [preData isEqualToData:[NSData dataWithBytes:perByte_b length:sizeof(perByte_b)]] ||
            [sufData isEqualToData:[NSData dataWithBytes:sufByte_b length:sizeof(sufByte_b)]]) {
            
            NSData *crcData = [data subdataWithRange:(NSMakeRange(data.length - 4, 2))];
            NSData *enData = [data subdataWithRange:(NSMakeRange(2, data.length - 6))];
            UInt16 order = [CJCRCHub computeCRC16WithData:enData type:(CJCRC16TypeModbus)];
            NSData *orderData = [NSData dataWithBytes:&order length:sizeof(order)];
            if ([crcData isEqualToData:orderData]) {
                isCompled = YES;
            } else {
                kFBtLog(@"CRC验证错误--%@", data);
            }
        }
    }
    return isCompled;
}

/**
 包头  功能码   时间戳    数据长度   值  CRC-16/MODBUS(反序)   包尾
 7F7F  3A    6881A533   0001    03      367B             F7F7
 */

/// 处理正确数据
- (void)handleCompledData:(NSData *)data periModel:(FBtPeriModel *)periModel {
    Byte *byte = (Byte *)[data bytes];
    
    uint8_t func = byte[2];
    UInt16 length = (byte[7] >> 8) + (byte[8]);
    NSData *timeData = [data subdataWithRange:(NSMakeRange(3, 4))];

    NSData *valueData = nil;
    if (length > 0) {
        valueData = [data subdataWithRange:(NSMakeRange(9, length))];
    }

    NSString *key = [timeData f_hexString];
    FBtMessageModel *messageModel = self.sendReceiveParams[key];
    if (messageModel) {
        messageModel.r_value = valueData;
        messageModel.r_data = data;
        [self receiveDecodeWithModel:messageModel];
        // 回调结果
        messageModel.state = FBtMessageStateSended;
        if (messageModel.didReceiveAction) {
            messageModel.didReceiveAction(messageModel);
        }
    } else {
        // 非发送数据
        FBtMessageModel *messageModel = [[FBtMessageModel alloc] init];
        messageModel.func = func;
        messageModel.periModel = periModel;
        // 握手判断
        [self handshakeMessageModel:messageModel];
    }
}

/// 错误数据处理分包
- (void)handleSubcontractPeriModel:(FBtPeriModel *)periModel {
    if (self.receiveCacheData.length <= 0) {
        return;
    }
    // 遍历寻找包头 0x7F7F/0x7E7E
    Byte *byte = (Byte *)[self.receiveCacheData bytes];
    NSInteger index = -1;
    for (NSInteger i = 0; i < self.receiveCacheData.length - 1; i++) {
        if ((byte[i] == 0x7F && byte[i + 1] == 0x7F) || (byte[i] == 0x7E && byte[i + 1] == 0x7E)) {
            index = i;
            break;
        }
    }
    if (index == -1) {
        return;
    }
    // 定位长度位
    NSInteger l0 = index + 7;
    NSInteger l1 = index + 8;
    if (l1 > self.receiveCacheData.length) {
        return;
    }
    // 判断无效数据长度
    UInt16 valueLength = byte[l0] + (byte[l1] << 8);
    if (valueLength > 512) {
        NSRange cacheRange = NSMakeRange(index + 1, self.receiveCacheData.length - (index + 1));
        self.receiveCacheData = [NSMutableData dataWithData:[self.receiveCacheData subdataWithRange:cacheRange]];
        [self handleSubcontractPeriModel:periModel];
        return;
    }
    // 判断缓存长度够不消息长度
    NSInteger messageLength = 9 + valueLength + 4;
    if ((index + messageLength) > self.receiveCacheData.length) {
        return;
    }
    // 完整数据
    NSData *compledData = [self.receiveCacheData subdataWithRange:(NSMakeRange(index, messageLength))];
    if ([self isCompledData:compledData]) {
        [self handleCompledData:compledData periModel:periModel];
        index = index + compledData.length;
    }
    // 下一轮循环
    NSRange cacheRange = NSMakeRange(index + 1, self.receiveCacheData.length - (index + 1));
    self.receiveCacheData = [NSMutableData dataWithData:[self.receiveCacheData subdataWithRange:cacheRange]];
    [self handleSubcontractPeriModel:periModel];
}

/// 发送数据
- (void)pushWithModel:(FBtMessageModel *)messageModel {
    if (messageModel.level == FBtMessageLevelPrior) {
        [self.sendMessageModels insertObject:messageModel atIndex:0];
    } else {
        [self.sendMessageModels addObject:messageModel];
    }
    [self startWriteTimer];
}

- (void)startWriteTimer {
    if (self.writeTimer) return;
    __weak typeof(self) wself = self;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    self.writeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    
    dispatch_source_set_timer(self.writeTimer,
                              dispatch_time(DISPATCH_TIME_NOW, 0),
                              (uint64_t)(self.writeInterval * NSEC_PER_SEC),
                              0);
    
    dispatch_source_set_event_handler(self.writeTimer, ^{
        [wself writeTimerAction];
    });
    dispatch_resume(self.writeTimer);
}

- (void)endWriteTimer {
    dispatch_source_cancel(self.writeTimer);
    self.writeTimer = nil;
}

/// 重置写入数据计时
- (void)resetWriteTimerWith:(CGFloat)interval {
    [self endWriteTimer];
    self.writeInterval = interval;
    [self startWriteTimer];
}

/// 写入数据计时
- (void)writeTimerAction {
    if (self.sendMessageModels.count > 0) {
        [self writeLoopAction];
    } else {
        [self endWriteTimer];
    }
}

/// 写入数据循环
- (void)writeLoopAction {
    if (self.sendMessageModels.count > 0) {
        FBtMessageModel *messageModel = [self.sendMessageModels firstObject];
        [self writeMessageModel:messageModel];
        if (self.sendMessageModels.count) {
            [self.sendMessageModels removeObjectAtIndex:0];
        }
    }
}

/// 蓝牙写入数据
- (void)writeMessageModel:(FBtMessageModel *)messageModel {
    NSData *data = messageModel.data;
    CBPeripheral *peri = messageModel.periModel.peri;
    CBCharacteristic *chara = messageModel.periModel.writeChara;
    CBCharacteristicWriteType type = CBCharacteristicWriteWithoutResponse;
    
    if (messageModel.writeType == FBtMessageWriteTypeWithoutResponse) {
        type = CBCharacteristicWriteWithoutResponse;
    } else if (messageModel.writeType == FBtMessageWriteTypeResponse) {
        type = CBCharacteristicWriteWithResponse;
    }
    
    if (data && peri && chara) {
        kFBtLog(@"发送数据--%@", [messageModel.data f_hexString]);
        __weak typeof(self) wself = self;
        [messageModel startTimer:^(FBtMessageModel *messageModel) {
            [wself pushTimeoutMessageModel:messageModel];
        }];
        if (messageModel.signal != FBtSig_heart &&
            messageModel.signal != FBtSig_handshakeAA &&
            messageModel.signal != FBtSig_handshakeAC &&
            messageModel.signal != FBtSig_handshakeAB) {
            self.sendReceiveParams[messageModel.key] = messageModel;
        }
        [peri writeValue:data forCharacteristic:chara type:type];
    }
}

/// messageModel蓝牙写入超时
- (void)pushTimeoutMessageModel:(FBtMessageModel *)messageModel {
    if (messageModel.didReceiveAction) {
        messageModel.didReceiveAction(messageModel);
    }
    [self.sendReceiveParams removeObjectForKey:messageModel.key];
}

/// 握手协议
- (void)handshakeMessageModel:(FBtMessageModel *)messageModel {
    UInt8 func = messageModel.func;
    FBtMessageModel *sendMessageMode = [[FBtMessageModel alloc] init];
    sendMessageMode.periModel = messageModel.periModel;
    if (func == 0x2A) {
        sendMessageMode.signal = FBtSig_handshakeAA;
    } else if (func == 0x2C) {
        sendMessageMode.signal = FBtSig_handshakeAC;
    } else if (func == 0x2B) {
        sendMessageMode.signal = FBtSig_handshakeAB;
        // 握手成功 心跳连接
        messageModel.periModel.dataState = FBtPeriDataSateHandshaked;
        [self startHeartTimer];
    }
    [sendMessageMode setupCompleData];
    [self pushWithModel:sendMessageMode];
}

- (void)startHeartTimer {
    if (self.heartTimer) return;
    __weak typeof(self) wself = self;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    self.heartTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    
    dispatch_source_set_timer(self.heartTimer,
                              dispatch_time(DISPATCH_TIME_NOW, 0),
                              (uint64_t)(5 * NSEC_PER_SEC),
                              0);
    
    dispatch_source_set_event_handler(self.heartTimer, ^{
        [wself heartTimerAction];
    });
    dispatch_resume(self.heartTimer);
}

- (void)endHeartTimer {
    dispatch_source_cancel(self.heartTimer);
    self.heartTimer = nil;
}

- (void)heartTimerAction {
    if (self.periModels.count <= 0) {
        [self endHeartTimer];
    }
    FBtMessageModel *messageModel = [[FBtMessageModel alloc] init];
    for (FBtPeriModel *periModel in self.periModels) {
        if (periModel.dataState == FBtPeriDataSateHandshaked) {
            messageModel.periModel = periModel;
            messageModel.signal = FBtSig_heart;
            [messageModel setupCompleData];
            [self pushWithModel:messageModel];
        }
    }
}

/// 重置Session
- (void)resetBtSession {
    [self endWriteTimer];
    [self endHeartTimer];
    
    self.receiveCacheData = [NSMutableData data];
    self.sendMessageModels = [NSMutableArray array];
    self.sendReceiveParams = [NSMutableDictionary dictionary];
}



@end
